Skip to content

# サイドバー / PDF パネルの折りたたみ対応と巨大 PDF ガード#294

Merged
yusuke0610 merged 3 commits into
mainfrom
feat/openAPI-typescript
May 31, 2026
Merged

# サイドバー / PDF パネルの折りたたみ対応と巨大 PDF ガード#294
yusuke0610 merged 3 commits into
mainfrom
feat/openAPI-typescript

Conversation

@yusuke0610

@yusuke0610 yusuke0610 commented May 31, 2026

Copy link
Copy Markdown
Owner

概要

職務経歴書編集まわりの画面で表示領域を広く使えるよう、サイドバーと**PDF 原本ビュー(右カラム)**をそれぞれ折りたたみ可能にした。あわせて、PDF 取り込み補助でブラウザのフリーズ / OOM を招く巨大ファイルを描画前に弾くガードを追加した。

対象コミット:

  • 284350e サイドバー折り畳み
  • 93e0881 heavy PDF guard

frontend のみの変更(backend / infra への影響なし)。

変更内容

1. サイドバーの折りたたみ(284350e

  • AuthenticatedLayoutsidebarCollapsed 状態を追加。ヘッダー右端の «(閉じる)ボタンでサイドバーを画面外へスライドし、本文領域を全幅に広げる。
  • 折りたたみ中は左上に固定の »(再展開)ボタンを表示。
  • サイドバータイトルと折りたたみボタンを横並びにする sidebarHeader を新設し、PC / モバイル両レイアウトに対応(モバイルではトップバー化したサイドバーでも折りたたみ可能)。
  • トランジション(transform / margin-left)でスライドを滑らかに。

2. PDF 原本ビューの折りたたみ(284350e

  • CareerResumeFormpdfCollapsed 状態を追加。右カラムを細い縦レール(pdfColCollapsed)に畳み、入力フォームを全幅に広げる。
  • 折りたたみ時はスプリッターと ResumePdfTracePanel を非レンダリングにし、トグルボタンのみ表示。
  • 縦レールではトグルを縦書き(writing-mode: vertical-rl)に、縦積みレイアウト(狭幅)では全幅の薄いバー + 横書きに切り替え。
  • aria-expanded / aria-label でアクセシビリティ対応。

3. 巨大 PDF のガード(93e0881

  • useResumeImportAssist に最大ファイルサイズ 20MB のガード(MAX_FILE_BYTES)を追加。超過時は file を保持せずエラー表示して描画前に弾く。
  • 目的は Cloud Run のコスト対策ではなく(取り込みは pdf.js によるブラウザ内描画のみでサーバー送信はしない)、PdfDocumentView の全ページ一括レンダリングでブラウザがフリーズ / OOM するのを防ぐこと。職務経歴書 PDF は通常数 MB のため、明らかに異常な巨大ファイルだけを弾く緩めの閾値。

4. レスポンシブ微調整(93e0881

  • shared.module.css で狭幅時のセクション余白 / フォーム gap を詰め、入力欄の表示幅を確保。

メッセージ管理

ハードコードを避けるルールに従い、新規 UI 文言は SSoT に集約:

  • UI_MESSAGES.SIDEBAR_COLLAPSE / SIDEBAR_EXPAND / PDF_PANEL_COLLAPSE / PDF_PANEL_EXPAND
  • IMPORT_ASSIST_MESSAGES.TOO_LARGE(limitMb)(動的パラメータ対応の関数形式)

テスト

  • useResumeImportAssist.test.ts に「20MB 超の巨大ファイルは弾いてエラーを出す(file は保持しない)」ケースを追加。実バイト列は確保せず size のみ巨大に見せて描画ガードを検証。

影響範囲 / 変更ファイル

frontend/src/App.module.css                         | サイドバー折りたたみのスタイル
frontend/src/components/AuthenticatedLayout.tsx     | サイドバー折りたたみ状態・ボタン
frontend/src/components/forms/CareerResumeForm.tsx  | PDF パネル折りたたみ状態・トグル
frontend/src/components/forms/CareerResumeForm.module.css | PDF レール/トグルのスタイル
frontend/src/constants/messages.ts                  | UI/取り込み補助メッセージ追加
frontend/src/hooks/career/useResumeImportAssist.ts  | 20MB ガード
frontend/src/hooks/career/useResumeImportAssist.test.ts | ガードのテスト
frontend/src/styles/shared.module.css               | 狭幅時の余白調整

8 files changed, 225 insertions(+), 16 deletions(-)

確認事項(レビュー観点)

  • 認証後レイアウト(サイドバー)の変更のため、E2E のナビゲーション / レイアウト確認が望ましい。
  • PDF パネル折りたたみは職務経歴書フォームの UI フローに該当。

Summary by CodeRabbit

  • New Features

    • Sidebar can now be collapsed/expanded to maximize workspace
    • PDF preview panel in resume form can be toggled collapsed/expanded
    • Resume upload file size validation (20MB limit) with error messaging
  • Improvements

    • Enhanced mobile layout with optimized spacing and responsive adjustments
    • Smooth animations for sidebar and panel state transitions
    • Improved accessibility with descriptive toggle button labels

@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 43 minutes and 3 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f328226-3e41-4b01-a0ee-c1d6200760b8

📥 Commits

Reviewing files that changed from the base of the PR and between 93e0881 and 7bb6b9a.

📒 Files selected for processing (6)
  • frontend/src/App.module.css
  • frontend/src/components/AuthenticatedLayout.tsx
  • frontend/src/components/forms/CareerResumeForm.module.css
  • frontend/src/components/forms/CareerResumeForm.tsx
  • frontend/src/hooks/career/useResumeImportAssist.test.ts
  • frontend/src/hooks/career/useResumeImportAssist.ts
📝 Walkthrough

Walkthrough

This PR adds collapsible sidebar and PDF panel features to the authenticated app layout and career resume form, enforces a 20MB file size limit for resume uploads, and refines responsive layout spacing. The changes include state management, conditional UI rendering, CSS animations, localized accessibility labels, and validation logic.

Changes

Collapsible UI & Resume Validation

Layer / File(s) Summary
UI Messages and File Size Validation Constants
frontend/src/constants/messages.ts
UI_MESSAGES adds sidebar/PDF panel toggle labels (SIDEBAR_COLLAPSE, SIDEBAR_EXPAND, PDF_PANEL_COLLAPSE, PDF_PANEL_EXPAND). IMPORT_ASSIST_MESSAGES adds a TOO_LARGE(limitMb) message builder for file rejection warnings.
Sidebar Collapse Feature
frontend/src/components/AuthenticatedLayout.tsx, frontend/src/App.module.css
AuthenticatedLayout introduces sidebarCollapsed state and conditionally renders a fixed re-open button when collapsed. The layout root toggles a .sidebarCollapsed modifier class. Sidebar header includes a collapse button with aria-label. App CSS defines the collapsed state transform (slide sidebar off-screen), .mainContent margin expansion, and mobile media query overrides for header borders and button sizing. Transition animation smooths margin-left changes.
Resume File Size Validation
frontend/src/hooks/career/useResumeImportAssist.ts, frontend/src/hooks/career/useResumeImportAssist.test.ts
useResumeImportAssist hook defines a 20MB (MAX_FILE_BYTES) limit and checks file size before state updates in handleFileChange. Oversized files trigger an early return with an error set to IMPORT_ASSIST_MESSAGES.TOO_LARGE(MAX_FILE_MB). Test verifies rejection of mocked 20MB+ files.
PDF Panel Collapse in Career Resume Form
frontend/src/components/forms/CareerResumeForm.tsx, frontend/src/components/forms/CareerResumeForm.module.css
CareerResumeForm adds pdfCollapsed state and conditionally hides the splitter and ResumePdfTracePanel when collapsed. A toggle button flips the state and displays localized aria-label. CSS defines .pdfToggle button styling and .pdfColCollapsed rail layout with vertical writing-mode for the text. Container query overrides switch the collapsed bar to full-width with horizontal text on stacked layouts (≤680px).
Responsive Layout Adjustments
frontend/src/styles/shared.module.css
Tighter spacing on screens ≤768px: reduced .section padding and decreased .form grid gap for improved visual density on narrow viewports.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AuthenticatedLayout
  participant CSS as App.module.css
  User->>AuthenticatedLayout: Click collapse button
  AuthenticatedLayout->>AuthenticatedLayout: sidebarCollapsed = true
  AuthenticatedLayout->>CSS: Apply .sidebarCollapsed modifier
  CSS->>CSS: Slide sidebar out via transform
  CSS->>CSS: Expand mainContent width
  Note over CSS: Smooth transition: margin-left animation
  User->>AuthenticatedLayout: Click re-open button
  AuthenticatedLayout->>AuthenticatedLayout: sidebarCollapsed = false
  AuthenticatedLayout->>CSS: Remove .sidebarCollapsed modifier
  CSS->>CSS: Slide sidebar back in, restore layout
Loading
sequenceDiagram
  participant User
  participant CareerResumeForm
  participant useResumeImportAssist
  User->>CareerResumeForm: Select resume file
  CareerResumeForm->>useResumeImportAssist: handleFileChange(file)
  useResumeImportAssist->>useResumeImportAssist: Check file.size >= MAX_FILE_BYTES
  alt File too large
    useResumeImportAssist->>useResumeImportAssist: error = TOO_LARGE(20)
    useResumeImportAssist-->>User: Display error message
  else File acceptable
    useResumeImportAssist->>useResumeImportAssist: Parse file, update state
    useResumeImportAssist-->>User: Show parsed trace
  end
Loading
sequenceDiagram
  participant User
  participant CareerResumeForm
  participant CSS as CareerResumeForm.module.css
  User->>CareerResumeForm: Click PDF toggle button
  CareerResumeForm->>CareerResumeForm: pdfCollapsed = true
  CareerResumeForm->>CSS: Apply .pdfColCollapsed class
  Note over CareerResumeForm: Hide ResumePdfTracePanel & splitter
  CSS->>CSS: Render vertical rail with rotated text
  Note over CSS: Form expands to full width
  User->>CareerResumeForm: Click toggle again
  CareerResumeForm->>CareerResumeForm: pdfCollapsed = false
  CareerResumeForm->>CSS: Remove .pdfColCollapsed class
  Note over CareerResumeForm: Show ResumePdfTracePanel & splitter
  CSS->>CSS: Restore side-by-side layout
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hopping through the code so fine,
Sidebars collapse, PDFs align,
File size guards keep uploads tight,
Responsive tweaks make mobile right!
Twitching nose at features bright— 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title in Japanese accurately describes the main changes: sidebar/PDF panel collapsibility and large PDF guard, matching the primary objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/openAPI-typescript

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
frontend/src/hooks/career/useResumeImportAssist.test.ts (1)

41-52: ⚡ Quick win

Add regression test for oversize selection after an existing valid file

Current case covers only initial empty state. Add a second flow: select valid PDF first, then oversize PDF, and assert file/fileName are cleared.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/hooks/career/useResumeImportAssist.test.ts` around lines 41 -
52, Add a regression test that covers selecting a valid PDF first and then an
oversize PDF to ensure the hook clears previous selection; in the test file for
useResumeImportAssist, after rendering the hook and simulating a valid File
selection via result.current.handleFileChange(makeChangeEvent(validPdf)), assert
result.current.file and fileName are set, then simulate the huge file selection
(as in existing test using Object.defineProperty on size) and assert
result.current.file and fileName are cleared (null) and result.current.error
equals IMPORT_ASSIST_MESSAGES.TOO_LARGE(20); reference the hook
useResumeImportAssist, the handler handleFileChange, the helper makeChangeEvent,
and the message IMPORT_ASSIST_MESSAGES.TOO_LARGE to locate where to add this
second flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/App.module.css`:
- Around line 57-59: The collapsed sidebar (.sidebarCollapsed .sidebar) is only
visually hidden but remains keyboard-focusable; update the collapse handling to
make the sidebar non-interactive when hidden by adding non-focusable and
non-pointer rules (e.g., set visibility:hidden and pointer-events:none or
display:none) and/or set aria-hidden="true" (or apply the inert attribute) on
the sidebar container when .sidebarCollapsed is active so its interactive
descendants are removed from the tab order and cannot receive pointer events.

In `@frontend/src/components/forms/CareerResumeForm.tsx`:
- Around line 247-271: The collapsed PDF column currently prevents
ResumePdfTracePanel from rendering when pdfCollapsed is true, which hides assist
errors (assist.error); update the component so assist errors remain surfaced
even when pdfCollapsed is true — e.g., render a lightweight error
indicator/button next to the pdf toggle or always render a minimal
ResumePdfTracePanelErrorView (referencing pdfCollapsed, ResumePdfTracePanel,
assist.error, setPdfCollapsed and UI_MESSAGES.PDF_PANEL_COLLAPSE/EXPAND) so
parse/oversize errors are visible and can toggle the full panel.

In `@frontend/src/hooks/career/useResumeImportAssist.ts`:
- Around line 97-100: The oversize-file early-return in the block that checks
"if (selected.size > MAX_FILE_BYTES)" only calls setError and returns, leaving
previous file state (file and fileName) stale; update that branch to also clear
the selected file state by calling setFile(null) and setFileName('') (or
appropriate empty values) before returning so the stale PDF is not shown,
keeping the error message from IMPORT_ASSIST_MESSAGES.TOO_LARGE(MAX_FILE_MB).

---

Nitpick comments:
In `@frontend/src/hooks/career/useResumeImportAssist.test.ts`:
- Around line 41-52: Add a regression test that covers selecting a valid PDF
first and then an oversize PDF to ensure the hook clears previous selection; in
the test file for useResumeImportAssist, after rendering the hook and simulating
a valid File selection via
result.current.handleFileChange(makeChangeEvent(validPdf)), assert
result.current.file and fileName are set, then simulate the huge file selection
(as in existing test using Object.defineProperty on size) and assert
result.current.file and fileName are cleared (null) and result.current.error
equals IMPORT_ASSIST_MESSAGES.TOO_LARGE(20); reference the hook
useResumeImportAssist, the handler handleFileChange, the helper makeChangeEvent,
and the message IMPORT_ASSIST_MESSAGES.TOO_LARGE to locate where to add this
second flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8515331f-838f-4d84-8776-ff072d4ef65e

📥 Commits

Reviewing files that changed from the base of the PR and between 808fb4a and 93e0881.

📒 Files selected for processing (8)
  • frontend/src/App.module.css
  • frontend/src/components/AuthenticatedLayout.tsx
  • frontend/src/components/forms/CareerResumeForm.module.css
  • frontend/src/components/forms/CareerResumeForm.tsx
  • frontend/src/constants/messages.ts
  • frontend/src/hooks/career/useResumeImportAssist.test.ts
  • frontend/src/hooks/career/useResumeImportAssist.ts
  • frontend/src/styles/shared.module.css

Comment thread frontend/src/App.module.css
Comment thread frontend/src/components/forms/CareerResumeForm.tsx
Comment thread frontend/src/hooks/career/useResumeImportAssist.ts
@yusuke0610
yusuke0610 merged commit 49db892 into main May 31, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant